/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appspot.trick.it.admin.controller;

import com.appspot.trick.it.admin.Constants;
import com.appspot.trick.it.admin.TrickAdmin;
import com.appspot.trick.it.admin.api.GoogleOauthAPIService;
import com.appspot.trick.it.admin.api.exception.CodeExchangeException;
import com.appspot.trick.it.admin.db.DBManager;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.oauth2.Oauth2;
import com.google.api.services.oauth2.model.Userinfo;
import java.io.IOException;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.URL;
import java.sql.SQLException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.web.WebView;

/**
 *
 * @author takahara
 */
public class OAuthController extends AnchorPane implements Initializable {
    
    @FXML
    public WebView oauthWebView;
    @FXML
    public HBox progressIndicatorHBox;
    
    /**
     * コンストラクタ
     */
    public OAuthController() {
        loadFXML();
    }
    
    /**
     * 初期化メソッド
     */
    private void loadFXML() {
        // ---------------------------------------------------
        // FXMLのロードと設定
        // ---------------------------------------------------
        FXMLLoader fxmlLoader = new FXMLLoader(TrickAdmin.class.getResource("fxml/oauth.fxml"));
        fxmlLoader.setRoot(this);
        // 自分自身をコントロールとして設定
        fxmlLoader.setController(this);
        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // プログレスの初期化
        progressIndicatorHBox.visibleProperty().bind(oauthWebView.getEngine().getLoadWorker().runningProperty());
        
        try {
            initWebView();
        } catch (IOException ex) {
            Logger.getLogger(OAuthController.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
    
    private void initWebView() throws IOException {
        // authorizationUrl取得
        final GoogleOauthAPIService googleOauthAPIService = new GoogleOauthAPIService();
        String authorizationUrl = googleOauthAPIService.getAuthorizationUrl();
        
        // 承認画面の初期化
        oauthWebView.getEngine().locationProperty().addListener(new ChangeListener<String>() {

            @Override
            public void changed(ObservableValue<? extends String> ov, String before, String after) {
                if (after.startsWith(googleOauthAPIService.getRedirectUri())) {
                    String[] tmp = after.split("code=");
                    String authorizationCode = tmp[1];

                    if (authorizationCode != null) {

                        try {
                            // Googleから承認情報を取得
                            Credential credential = googleOauthAPIService.exchangeCode(authorizationCode);

                            // ユーザー情報の取得
                            Userinfo userinfo = getUserInfo(credential);

                            // 承認情報をDBに保存
                            DBManager.insertOrUpdateOauthMst(
                                    DBManager.getConn(),
                                    userinfo.getEmail(),
                                    userinfo.getId(),
                                    credential.getAccessToken(),
                                    credential.getRefreshToken());

                            // 承認ステージを閉じる
                            TrickAdmin.getInstance().closeOAuthStage();
                            
                            // アカウントチョイスボックスの初期化

                        } catch (CodeExchangeException | SQLException | IOException ex) {
                            Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }

        });

        // 新しいCookieManagerを生成し、WebViewのCookieをクリアーする
        final CookieManager manager = new CookieManager();
        manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
        CookieHandler.setDefault(manager);

        // 承認画面の表示
        oauthWebView.getEngine().load(authorizationUrl);
        oauthWebView.setVisible(true);
    }
    
    /**
     * ユーザー情報の取得
     *
     * @param credentials
     * @return
     */
    private Userinfo getUserInfo(Credential credentials) throws IOException {
        Oauth2 userInfoService
                = new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credentials)
                .setApplicationName(Constants.APPLICATION_NAME)
                .build();
        Userinfo userInfo = userInfoService.userinfo().get().execute();

        return userInfo;
    }

}
